package com.qianli.cashmama.product.server.controller.pay2;


import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.jsoniter.JsonIterator;
import com.jsoniter.any.Any;
import com.jsoniter.output.JsonStream;
import com.qianli.cashmama.product.server.controller.pay.HttpUtil;
import com.qianli.cashmama.product.server.controller.pay.OpenApiResponse;
import com.qianli.cashmama.product.server.controller.pay.PayUrlResponse;
import com.qianli.cashmama.product.server.controller.pay.RepayRequest;
import com.qianli.cashmama.product.server.dao.PayCallbackLogDao;
import com.qianli.cashmama.product.server.dao.PayRequestLogDao;
import com.qianli.cashmama.product.server.entity.ClReceiverDetailEntity;
import com.qianli.cashmama.product.server.entity.PayCallbackLogEntity;
import com.qianli.cashmama.product.server.entity.PayRequestLogEntity;
import com.qianli.cashmama.product.server.job.SendToMerchantData;
import com.robert.vesta.util.IdUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

@RestController
@RequestMapping("/pay/tarspay")
public class TarspayPayController {

    private static final Log LOGGER = LogFactory.getLog(TarspayPayController.class);

    private static String tarspayPublicKey = "03029c655932f22aee81034d109795fbd7e23ca173ca27e195091d434e593a2e0f";


    @NacosValue(value = "${tarspay.pay.private.key:f64d567efbb9246f9b17cf3df6db990ddf621b500e88eddd4faba4982302535f}", autoRefreshed = true)
    private String privateKey;
    @NacosValue(value = "${tarspay.pay.public.key:0283890b0cc31b56279f42b4e9d628c790a6e7ed5e68bc8969d5bf26f871e8ff55}", autoRefreshed = true)
    private String publicKey;

    @NacosValue(value = "${tarspay.pay.productId:M1669884597}", autoRefreshed = true)
    private String productId;

    @NacosValue(value = "${tarspay.pay.notifyUrl:http://147.139.37.96:9101/pay/tarspay/callback}", autoRefreshed = true)
    private String notifyUrl;


    @NacosValue(value = "${tarspay.pay.openapi:https://payment.tarspay.com}", autoRefreshed = true)
    private String openapi;


    @Autowired
    private PayRequestLogDao payRequestLogDao;

    @Autowired
    private PayCallbackLogDao payCallbackLogDao;


    //创建订单
    @RequestMapping("/pay/url")
    public OpenApiResponse create(@RequestBody SendToMerchantData request) {
        LOGGER.info("==tarspaypay 请求支付链接 ==,request1:{}", JSON.toJSON(request));
        String bizData = request.getBizData();
        if (StringUtils.isEmpty(bizData)) {
            return new OpenApiResponse(400, "start repayment exception2");
        }
        RepayRequest deserialize1 = JsonIterator.deserialize(bizData, RepayRequest.class);

        Any deserialize = JsonIterator.deserialize(deserialize1.getExtraInfo());
        String userName = "default";
        ClReceiverDetailEntity clReceiverDetailEntity = payCallbackLogDao.getOneByMobile(deserialize.get("tel").toString());
        if (clReceiverDetailEntity != null) {
            userName = clReceiverDetailEntity.getName();
        }
        if (StringUtils.isEmpty(userName)) {
            userName = "default";
        }
        String orderNoFor3d = IdUtils.genId() + "";
        PayRequestLogEntity payRequestLogEntity = new PayRequestLogEntity()
                .setTradeNo(deserialize1.getOrderNo())
                .setOrderNo(orderNoFor3d)
                .setOrderAmount(new BigDecimal(deserialize.get("orderAmount").toString()))
                .setTel(deserialize.get("tel").toString())
                .setUserName(userName);

        payRequestLogDao.insert(payRequestLogEntity);
        PayRequestLogEntity payRequestLogEntity1 = payRequestLogDao.selectByTripleOrderNo(orderNoFor3d);

        try {
             TarspayPaymentParam param = getCreateParam(payRequestLogEntity1);
            ECSDAKit kit = new ECSDAKit(privateKey);

            String jsonBody = JSON.toJSONString(param);
            LOGGER.info("==tarspaypay 访问支付链接接口1 ==,jsonBody:{}", jsonBody);

            TreeMap tree = new TreeMap(JsonIterator.deserialize(jsonBody).asMap());
            String signure = getSignure(tree);

            String nounce = String.valueOf((System.currentTimeMillis()) + 5000);

            String data = "POST" + "|/api/pay/unifiedOrder|" + nounce + "|" + signure;
            String sign = kit.sign(data.getBytes(StandardCharsets.UTF_8));

            //签名头
            Map<String, String> headerMap = makeSignHeaders(nounce, sign);
            LOGGER.info("==tarspaypay 访问支付链接接口2 ==,headerMap:{}", JsonStream.serialize(headerMap));

            String url = openapi + "/api/pay/unifiedOrder";

            String result = HttpUtil.postCurl(url, headerMap, jsonBody);
            LOGGER.info("==tarspaypay 访问支付链接接口3 ==,res:{}",result);

            if(StringUtils.isEmpty(result)){
                return new OpenApiResponse(400, "get payLink failed");
            }

            Any resultJson = JsonIterator.deserialize(result);
            LOGGER.info("==tarspaypay 访问支付链接接口4 ==,resultJson:{}",resultJson.toString());

            payRequestLogEntity1.setCode(resultJson.get("code").toString())
                    .setMessage(resultJson.get("msg").toString());
            if (0 == resultJson.get("code").toInt()) {
                LOGGER.info("==tarspaypay 访问支付链接接口 ==,code:{}",resultJson.get("code").toInt());
                payRequestLogEntity1.setPayOrderId(IdUtils.genId() + "")
                        .setCode(resultJson.get("code").toString())
                        .setPayOrderId(resultJson.get("data").get("payOrderId").toString())
                        .setPayUrl(resultJson.get("data").get("payUrl").toString());

                payRequestLogDao.updateByPrimaryKey(payRequestLogEntity1);
                PayUrlResponse payUrlResponse = new PayUrlResponse()
                        .setJumpUrl(resultJson.get("data").get("payUrl").toString());
                return new OpenApiResponse(200, "success").setData(payUrlResponse);
            }
            LOGGER.info("==tarspaypay 请求支付链接 sign ==,request2:{}", JSON.toJSON(param));
        } catch (Exception e) {
            LOGGER.error("==tarspaypay 请求支付链接 sign 异常==", e);
            return new OpenApiResponse(400, "start repayment exception");
        }


        return new OpenApiResponse(400, "create repayment link failed");
    }

    private TarspayPaymentParam getCreateParam(PayRequestLogEntity payRequestLogEntity) {
        TarspayPaymentParam param = new TarspayPaymentParam();
        param.setMchNo(productId);
        param.setMchOrderNo(payRequestLogEntity.getOrderNo());
        param.setAmount(payRequestLogEntity.getOrderAmount().longValue() + "");
        param.setCustomerName(payRequestLogEntity.getUserName());
        param.setWayCode("CASHIER");
        String mobile = payRequestLogEntity.getTel();
//        param.setCustomerContact(mobile.substring(0, 4) + "***" + mobile.substring(7));
        param.setCustomerContact(mobile);
        param.setNotifyUrl(notifyUrl);
        param.setReturnUrl(notifyUrl);
        param.setCurrency("INR");
        return param;
    }


    //支付异步回调

    @RequestMapping("/callback")
    public String payCallBack(@RequestBody TarspayOrderNotifyDTO dto) {
        String content = JSON.toJSONString(dto);
//        String signature = request.getHeader("X-RESP-SIGNATURE");
//        boolean b = ECSDAKit.verifyEcdsaSignature(content, signature, tarspayPublicKey);
        boolean b = true;
        LOGGER.info("==tarspaypay 回调  payCallBack ==,b:{}",b);
        if (b) {
            /**
             * 商户的业务逻辑
             */
            try {
                PayCallbackLogEntity payCallbackLogEntity = new PayCallbackLogEntity()
                        .setCode(dto.getState( ))
                        .setMchId(dto.getMchNo())
                        .setTradeNo(dto.getMchOrderNo())
//                        .setProductId(Integer.valueOf(request.getMerchantNo()))
                        .setOrderAmount(new BigDecimal(dto.getPayAmount()))
                        .setPayOrderId(dto.getPayOrderId())
                        .setPaySuccessTime(System.currentTimeMillis()+"")
//                        .setMessage()
                        .setExtra(dto.getFailReason());

                payCallbackLogDao.insert(payCallbackLogEntity);
                LOGGER.info("==tarspaypay 回调  payCallBack success ==");
            } catch (Exception e) {
                LOGGER.error("==tarspaypay 回调 payCallBack ==", e);
                return "DENY";
            }
            return "OK";
        }
        return "DENY";
    }


    //同步给催收，还款成功
    public void tellCollectionPaid() {

    }



    public static void main(String[] args) {
        //代收
        payCreate();
        //代付
//        payOutCreate();
        //代收查询
//        payInInfo();
        //代付查询
//        payOutInfo();
    }

    public static String payCreate() {
        ECSDAKit kit = new ECSDAKit("f64d567efbb9246f9b17cf3df6db990ddf621b500e88eddd4faba4982302535f");
        Map<String, Object> request = new HashMap<>();

        request.put("mchOrderNo", "D" + System.currentTimeMillis());
        request.put("mchNo", "M1669884597");
        request.put("amount", "100.00");
        request.put("currency", "INR");
        request.put("wayCode", "CASHIER");
        request.put("customerName", "fas fag");
        request.put("notifyUrl","http://www.baidu.com");
        request.put("returnUrl", "http://www.baidu.com");

        String jsonBody = JSON.toJSONString(request);

        TreeMap tree = new TreeMap(request);
        String signure = getSignure(tree);
        String nounce = String.valueOf((System.currentTimeMillis()) + 5000);
        String data = "POST" + "|/api/pay/unifiedOrder|" + nounce + "|" + signure;
        String sign = kit.sign(data.getBytes(StandardCharsets.UTF_8));
        //签名头
        Map<String, String> header = new HashMap<>();
        //public key
        header.put("X-API-KEY", "0283890b0cc31b56279f42b4e9d628c790a6e7ed5e68bc8969d5bf26f871e8ff55");
        header.put("X-API-NONCE", nounce);
        header.put("X-API-SIGNATURE", sign);
        String result = HttpUtil.postCurl("https://payment.tarspay.com/api/pay/unifiedOrder", header, jsonBody);

        LOGGER.info("====,res:{}",result);
//        //发送请求到客户端通知地址
//        HttpResponse execute = HttpUtil
//                //测试环境
//                .createPost("https://payment-test.tarspay.com/api/pay/unifiedOrder")
//                //正式环境
////                .createPost("https://payment.tarspay.com/api/pay/unifiedOrder")
//                .headerMap(headerMap, false)
//                .body(jsonBody)
//                .setConnectionTimeout(60 * 1000)
//                .setReadTimeout(3 * 60 * 1000)
//                .execute();
//        System.out.println(JSON.toJSONString(execute.body()));
        return "JSON.toJSONString(execute.body())";
    }
//
//    public static String payOutCreate() {
//        Map<String, Object> request = new HashMap<>();
//        //private key
//        ECSDAKit kit = new ECSDAKit(privateKey);
//        request.put("mchOrderNo", "D" + System.currentTimeMillis());
//        request.put("mchNo", "your mchNo");
//        request.put("amount", "100");
//        request.put("currency", "currency");
//        request.put("customerContact", "customerContact");
//        request.put("customerAccountNumber", "customerAccountNumber");
//        request.put("wayCode", "wayCode");
//        request.put("notifyUrl", "https://www.baidu.com");
//        request.put("customerName", "customerName");
//        request.put("customerEmail", "customerEmail");
//
//        //印度入参，其他国家不需要
//        request.put("bankName", "bank of maharashtra");
//        request.put("ifsc", "ifsc");
//        String jsonBody = JSON.toJSONString(request);
//        System.out.println(jsonBody);
//        TreeMap tree = new TreeMap(request);
//        String signure = getSignure(tree);
//        String nounce = String.valueOf((System.currentTimeMillis()) + 5000);
//        String data = "POST" + "|/api/payOut/unifiedOrder|" + nounce + "|" + signure;
//        String sign = kit.sign(data.getBytes(StandardCharsets.UTF_8));
//        System.out.println(sign);
////        //签名头
//        Map<String, String> headerMap = makeSignHeaders(nounce, sign);
////        //发送请求到客户端通知地址
////        HttpResponse execute = HttpUtil
////                //测试环境
////                .createPost("https://payment-test.tarspay.com/api/payOut/unifiedOrder")
////                //正式环境
//////                .createPost("https://payment.tarspay.com/api/payOut/unifiedOrder")
////                .headerMap(headerMap, false)
////                .body(jsonBody)
////                .setConnectionTimeout(60 * 1000)
////                .setReadTimeout(3 * 60 * 1000)
////                .execute();
////        System.out.println(JSON.toJSONString(execute.body()));
////        return JSON.toJSONString(execute.body());
//        return "";
//    }
//
//    public static String payInInfo() {
//        Map<String, Object> request = new HashMap<>();
//
//        //ECSDAKit 可以从API文档中获取
//        //private key
//        ECSDAKit kit = new ECSDAKit(privateKey);
//        //your mchNo
//        request.put("mchNo", "your mchNo");
//        //平台订单号和商户订单号两者必须有一个不为空
//        request.put("mchOrderNo", "D");
//        request.put("payOrderId", "");
//
//        String jsonBody = JSON.toJSONString(request);
//
//        TreeMap tree = new TreeMap(request);
//        String signure = getSignure(tree);
//        String nounce = String.valueOf((System.currentTimeMillis()) + 5000);
//        String data = "POST" + "|/api/payInInfo|" + nounce + "|" + signure;
//        String sign = kit.sign(data.getBytes(StandardCharsets.UTF_8));
//        //签名头
//        Map<String, String> headerMap = makeSignHeaders(nounce, sign);
//        String result = HttpUtil.postPageSsL("https://payment-test.tarspay.com/api/payInInfo", headerMap, jsonBody);
//        LOGGER.info("====,res:{}",result);
//
//        //发送请求到客户端通知地址
////        HttpResponse execute = HttpUtil
////                //测试环境
////                .createPost("https://payment-test.tarspay.com/api/payInInfo")
////                //正式环境
//////                .createPost("https://payment.tarspay.com/api/pay/unifiedOrder")
////                .headerMap(headerMap, false)
////                .body(jsonBody)
////                .setConnectionTimeout(60 * 1000)
////                .setReadTimeout(3 * 60 * 1000)
////                .execute();
//        return "";
//    }
//
//
//    public static String payOutInfo() {
//        Map<String, Object> request = new HashMap<>();
//
//        //ECSDAKit 可以从API文档中获取
//        //private key
//        ECSDAKit kit = new ECSDAKit(privateKey);
//        //your mchNo
//        request.put("mchNo", "your mchNo");
//        //平台订单号和商户订单号两者必须有一个不为空
//        request.put("mchOrderNo", "D");
//        request.put("payOrderId", "");
//
//        String jsonBody = JSON.toJSONString(request);
//
//        TreeMap tree = new TreeMap(request);
//        String signure = getSignure(tree);
//        String nounce = String.valueOf((System.currentTimeMillis()) + 5000);
//        String data = "POST" + "|/api/payOutInfo|" + nounce + "|" + signure;
//        String sign = kit.sign(data.getBytes(StandardCharsets.UTF_8));
//        //签名头
//        Map<String, String> headerMap = makeSignHeaders(nounce, sign);
//        //发送请求到客户端通知地址
////        HttpResponse execute = HttpUtil
////                //测试环境
////                .createPost("https://payment-test.tarspay.com/api/payOutInfo")
////                //正式环境
//////                .createPost("https://payment.tarspay.com/api/pay/unifiedOrder")
////                .headerMap(headerMap, false)
////                .body(jsonBody)
////                .setConnectionTimeout(60 * 1000)
////                .setReadTimeout(3 * 60 * 1000)
////                .execute();
////        System.out.println(JSON.toJSONString(execute.body()));
//        return "";
//    }
//
    public Map<String, String> makeSignHeaders(String nounce, String sign) {
        Map<String, String> header = new HashMap<>();
        //public key
        header.put("X-API-KEY", publicKey);
        header.put("X-API-NONCE", nounce);
        header.put("X-API-SIGNATURE", sign);
        return header;
    }
//
//
    public static String getSignure(TreeMap tree) {
        StringBuffer sb = new StringBuffer();
        tree.forEach((k, v) -> {
            sb.append(k).append("=").append(v).append("&");
        });
        String s = sb.toString();
        String substring = s.substring(0, s.length() - 1);
        return substring;
    }



}
